﻿
// #define TEST

using System;
using System.IO;
using System.Linq;
using System.Net;
using Xunit;
using Xunit.Extensions;

namespace EmperialApps.WeatherSpark.Data {

    public class TestPlace {

        [Theory]
        [InlineData( "Austin, TX", null, "Austin, TX" )]
        [InlineData( "Austin, TX", "Travis", "Austin, TX (Travis)" )]
        [InlineData( "3 Miles SE Antioch CA", null, "Antioch, CA; SE 5\u200akm" )]
        public void FullName_WhenPlaceHasCounty_IncludesCounty( string name, string county, string expected ) {
            var place = Place.Create( default( Units ), default( Coordinate ), name, county );

            string actual = place.FullName;

            Assert.Equal( expected, actual );
        }

        [Theory]
        [InlineData( "Austin, TX", "Austin, TX" )]
        [InlineData( "3 Miles SE Antioch CA", "Antioch, CA" )]
        public void CityName_WhenPlaceHasDistance_DoesNotIncludeDistance( string name, string expected ) {
            var place = Place.Create( default( Units ), default( Coordinate ), name );

            string actual = place.CityName;

            Assert.Equal( expected, actual );
        }


        [Theory]
        [InlineData( "Austin TX", "Austin, TX", null )]
        [InlineData( "Austin, TX", "Austin, TX", null )]
        [InlineData( "Austin TX|LINK", "Austin, TX", "LINK" )]
        [InlineData( "Austin, TX|LINK", "Austin, TX", "LINK" )]
        public void Create_GivenCityNameAndLink_SeparatesLinkAndAddsAppropriateComma( string name, string expectedName, string expectedLink ) {
            var expected = Tuple.Create( expectedName, expectedLink );

            var place = Place.Create( default( Units ), default( Coordinate ), name );
            var actual = Tuple.Create( place.Name, place.Link );

            Assert.Equal( expected, actual );
        }

        [Theory]
        [InlineData( "6 Miles WNW Guthrie Center IA", Units.Imperial, "Guthrie Center, IA; WNW 6\u200ami" )]
        [InlineData( "6 Miles WNW Guthrie Center IA", Units.Metric, "Guthrie Center, IA; WNW 10\u200akm" )]
        [InlineData( "7 Miles E Spearsville LA", Units.Imperial, "Spearsville, LA; E 7\u200ami" )]
        [InlineData( "7 Miles E Spearsville LA", Units.Metric, "Spearsville, LA; E 11\u200akm" )]
        [InlineData( "3 Miles SE Antioch CA", Units.Imperial, "Antioch, CA; SE 3\u200ami" )]
        [InlineData( "3 Miles SE Antioch CA", Units.Metric, "Antioch, CA; SE 5\u200akm" )]
        public void Create_GivenCityNameWithDistance_MovesConvertedDistanceToEnd( string name, Units units, string expected ) {
            var place = Place.Create( units, default( Coordinate ), name );
            string actual = place.Name;

            Assert.Equal( expected, actual );
        }


        [Theory]
        [InlineData( "Austin TX", "Austin, TX", "", "Travis", true )]
        [InlineData( "Austin, TX", "Austin, TX", "Travis", "", true )]
        [InlineData( "Austin, TX", "Austin, MO", "Travis", "Dunklin", false )]
        public void Equals_ReturnsTrueRegardlessOfCounty( string name1, string name2, string county1, string county2, bool expected ) {
            var place1 = Place.Create( default( Units ), default( Coordinate ), name1, county1 );
            var place2 = Place.Create( default( Units ), default( Coordinate ), name2, county2 );

            bool actual = place1.Equals( place2 );

            Assert.Equal( expected, actual );
        }

        [Theory]
        [InlineData( CityFile.Austin )]
        [InlineData( CityFile.Austin_TX )]
        [InlineData( CityFile.Eidal )]
        [InlineData( CityFile.London )]
        [InlineData( CityFile.Montevideo )]
        [InlineData( CityFile.Rome )]
        [InlineData( CityFile.Sammamish )]
        [InlineData( CityFile.Sydney )]
        [InlineData( CityFile.Tokyo )]
        public void Load_GivenValidSource_ReturnsExpectedCities( CityFile file ) {
            var expected = GetCityData( file );

            var actual = LoadCities( file );

            Assert.Equal( expected, actual, Equal.PlaceComparer );
        }

#if !DEBUG || TEST
        [Theory]
#endif
        [InlineData( CityFile.Austin )]
        [InlineData( CityFile.Austin_TX )]
        [InlineData( CityFile.Eidal )]
        [InlineData( CityFile.London )]
        [InlineData( CityFile.Montevideo )]
        [InlineData( CityFile.Rome )]
        [InlineData( CityFile.Sydney )]
        [InlineData( CityFile.Tokyo )]
        public void Load_GivenLatestSource_ReturnsExpectedCities( CityFile file ) {
            var expected = GetCityData( file );

            var actual = DownloadCities( file );
            var missing = expected.Except( actual ).ToArray( );
            var extra = actual.Except( expected ).ToArray( );

            if( missing.Length != extra.Length )
                Assert.True( false, string.Format( "Download returned unexpected data:{0}Missing: {{ {1} }}{0}Extra:   {{ {2} }}",
                    Environment.NewLine, string.Join( ", ", missing ), string.Join( ", ", extra ) ) );
            else if( missing.Length + extra.Length > 2 )
                Assert.Equal( missing, extra, Equal.PlaceComparer );
        }


        [Theory]
        [InlineData( "BE", "Walloon" )]
        [InlineData( "ZA", "Walloon" )]
        [InlineData( "CO", "Bogota D.C." )]
        public void Corrections_ForLink_LoadedFromModifiedSaveValue_ReturnsModifiedResults( string country, string adminName1 ) {
            var unmodified = default( Place.Corrections );
            var modified = GetModifiedCorrections( unmodified );

            string expected = adminName1;
            string actual = adminName1;
            unmodified.ForLink( country, ref expected );
            modified.ForLink( country, ref actual );

            Assert.NotEqual( expected, actual );
        }

        [Theory]
        [InlineData( "Metropolitan" )]
        [InlineData( "Metropolis" )]
        public void Corrections_SkipPart_LoadedFromModifiedSaveValue_ReturnsModifiedResults( string part ) {
            var unmodified = default( Place.Corrections );
            var modified = GetModifiedCorrections( unmodified );

            byte skip;
            var expected = Pair.Create( unmodified.SkipPart( part, out skip ), skip );
            var actual = Pair.Create( modified.SkipPart( part, out skip ), skip );

            Assert.NotEqual( expected, actual );
        }

        private static Place.Corrections GetModifiedCorrections( Place.Corrections unmodified ) {
            string save = unmodified.Save( );
            string saveModified = save.Replace( "Metropolitan", "Metropolis" ).Replace( "BE", "ZA" ).Replace( "Bogotá", "9" );
            return Place.Corrections.Load( saveModified );
        }


        #region Utility

        private static Place[][] _fileData = new Place[Enum.GetValues( typeof( CityFile ) ).Length][];
        private static Place[] GetCityData( CityFile file ) {
            int index = (int)file;
            if( _fileData[index] == null ) {
                _fileData[index] =
                    file == CityFile.Austin_TX ? new[] {
                        new Place( new Coordinate( 30.27, -97.74 ), "Austin, TX, US", "Travis", "http://www.yr.no/place/United_States/Texas/Austin~4671654/" ),
                        new Place( new Coordinate( 26.35, -98.20 ), "Austin Gardens Colonia, TX, US", "Hidalgo", "http://www.yr.no/place/United_States/Texas/Austin_Gardens_Colonia~4671691/" )
                    } :
                    file == CityFile.Austin ? new[] {
                        new Place( new Coordinate( 30.27, -97.74 ), "Austin, TX, US", "Travis", "http://www.yr.no/place/United_States/Texas/Austin~4671654/" ),
                        new Place( new Coordinate( 49.95, -98.94 ), "Austin, MB, CA", "", "http://www.yr.no/place/Canada/Manitoba/Austin~5888406/" ),
                        new Place( new Coordinate( 45.18, -72.28 ), "Austin, QC, CA", "Estrie", "http://www.yr.no/place/Canada/Quebec/Austin~5888403/" ),
                        new Place( new Coordinate( 41.89, -87.76 ), "Austin, IL, US", "Cook", "http://www.yr.no/place/United_States/Illinois/Austin~4883837/" ),
                        new Place( new Coordinate( 35.00, -91.98 ), "Austin, AR, US", "Lonoke", "http://www.yr.no/place/United_States/Arkansas/Austin~4099974/" ),
                        new Place( new Coordinate( 38.76, -85.81 ), "Austin, IN, US", "Scott", "http://www.yr.no/place/United_States/Indiana/Austin~4254010/" ),
                        new Place( new Coordinate( 34.64, -90.45 ), "Austin, MS, US", "Tunica", "http://www.yr.no/place/United_States/Mississippi/Austin~4416697/" ),
                        new Place( new Coordinate( 41.74, -84.69 ), "Austin, MI, US", "Hillsdale", "http://www.yr.no/place/United_States/Michigan/Austin~4984591/" ),
                        new Place( new Coordinate( 18.81, -72.52 ), "Austin, OU, HT", "", "http://www.yr.no/place/Haiti/Ouest/Austin~3731004/" ),
                        new Place( new Coordinate( 36.83, -86.02 ), "Austin, KY, US", "Barren", "http://www.yr.no/place/United_States/Kentucky/Austin~4282830/" ),
                        new Place( new Coordinate( 41.63, -78.09 ), "Austin, PA, US", "Potter", "http://www.yr.no/place/United_States/Pennsylvania/Austin~5178713/" ),
                        new Place( new Coordinate( 43.67, -92.97 ), "Austin, MN, US", "Mower", "http://www.yr.no/place/United_States/Minnesota/Austin~5016884/" ),
                        new Place( new Coordinate( 35.44, -92.53 ), "Austin, AR, US", "Conway", "http://www.yr.no/place/United_States/Arkansas/Austin~4099973/" ),
                        new Place( new Coordinate( 38.50, -94.30 ), "Austin, MO, US", "Cass", "http://www.yr.no/place/United_States/Missouri/Austin~4375358/" ),
                        new Place( new Coordinate( 36.16, -90.16 ), "Austin, MO, US", "Dunklin", "http://www.yr.no/place/United_States/Missouri/Austin~4375359/" ),
                        new Place( new Coordinate( 39.44, -83.22 ), "Austin, OH, US", "Ross", "http://www.yr.no/place/United_States/Ohio/Austin~4505641/" ),
                        new Place( new Coordinate( 46.28, -87.46 ), "Austin, MI, US", "Marquette", "http://www.yr.no/place/United_States/Michigan/Austin~4984592/" ),
                        new Place( new Coordinate( 38.67, -112.12 ), "Austin, UT, US", "Sevier", "http://www.yr.no/place/United_States/Utah/Austin~5534614/" ),
                        new Place( new Coordinate( 46.64, -112.25 ), "Austin, MT, US", "Lewis and Clark", "http://www.yr.no/place/United_States/Montana/Austin~5637923/" ),
                        new Place( new Coordinate( 47.99, -122.54 ), "Austin, WA, US", "Island", "http://www.yr.no/place/United_States/Washington/Austin~5786003/" ),
                        new Place( new Coordinate( 44.05, -82.99 ), "Port Austin, MI, US", "Huron", "http://www.yr.no/place/United_States/Michigan/Port_Austin~5006221/" ),
                        new Place( new Coordinate( 38.78, -107.95 ), "Austin, CO, US", "Delta", "http://www.yr.no/place/United_States/Colorado/Austin~5412364/" ),
                        new Place( new Coordinate( 39.49, -117.07 ), "Austin, NV, US", "Lander", "http://www.yr.no/place/United_States/Nevada/Austin~5499537/" ),
                        new Place( new Coordinate( -35.14, 147.35 ), "Mount Austin, NSW, AU", "Wagga Wagga", "http://www.yr.no/place/Australia/New_South_Wales/Mount_Austin~8349123/" ),
                        new Place( new Coordinate( 35.53, -92.79 ), "Austin, AR, US", "Van Buren", "http://www.yr.no/place/United_States/Arkansas/Austin~4099975/" ),
                        new Place( new Coordinate( 35.20, -88.24 ), "Austin, TN, US", "Hardin", "http://www.yr.no/place/United_States/Tennessee/Austin~4603359/" ),
                        new Place( new Coordinate( 44.60, -118.50 ), "Austin, OR, US", "Grant", "http://www.yr.no/place/United_States/Oregon/Austin~5711916/" ),
                        new Place( new Coordinate( -25.97, 28.15 ), "Glen Austin, GP, ZA", "", "http://www.yr.no/place/South_Africa/Gauteng/Glen_Austin~1001775/" ),
                        new Place( new Coordinate( 41.59, -71.66 ), "Austin, RI, US", "Washington", "http://www.yr.no/place/United_States/Rhode_Island/Austin~5220732/" ),
                        new Place( new Coordinate( 37.24, -122.00 ), "Austin, CA, US", "Santa Clara", "http://www.yr.no/place/United_States/California/Austin~5325278/" ),
                        new Place( new Coordinate( 36.32, -80.98 ), "Austin, NC, US", "Wilkes", "http://www.yr.no/place/United_States/North_Carolina/Austin~4453191/" ),
                        new Place( new Coordinate( 42.81, -76.47 ), "Austin, NY, US", "Cayuga", "http://www.yr.no/place/United_States/New_York/Austin~5107539/" ),
                        new Place( new Coordinate( 34.99, -91.96 ), "Old Austin, AR, US", "Lonoke", "http://www.yr.no/place/United_States/Arkansas/Old_Austin~4124678/" ),
                        new Place( new Coordinate( 36.38, -82.35 ), "Austin Springs, TN, US", "Washington", "http://www.yr.no/place/United_States/Tennessee/Austin_Springs~4603390/" ),
                        new Place( new Coordinate( 36.49, -88.63 ), "Austin Springs, TN, US", "Weakley", "http://www.yr.no/place/United_States/Tennessee/Austin_Springs~4603391/" ),
                        new Place( new Coordinate( 33.21, -87.50 ), "Austin Subdivision, AL, US", "Tuscaloosa", "http://www.yr.no/place/United_States/Alabama/Austin_Subdivision~4830829/" ),
                        new Place( new Coordinate( 41.24, -80.86 ), "Austin Village, OH, US", "Trumbull", "http://www.yr.no/place/United_States/Ohio/Austin_Village~5146246/" ),
                        new Place( new Coordinate( 27.98, -82.24 ), "Austin Oaks, FL, US", "Hillsborough", "http://www.yr.no/place/United_States/Florida/Austin_Oaks~7216240/" ),
                        new Place( new Coordinate( 1.56, 103.78 ), "Taman Mount Austin, Johor, MY", "", "http://www.yr.no/place/Malaysia/Johor/Taman_Mount_Austin~7619698/" ),
                        new Place( new Coordinate( 43.62, -82.94 ), "Austin Center, MI, US", "Sanilac", "http://www.yr.no/place/United_States/Michigan/Austin_Center~4984594/" ),
                        new Place( new Coordinate( 42.79, -83.51 ), "Austin Corners, MI, US", "Oakland", "http://www.yr.no/place/United_States/Michigan/Austin_Corners~4984596/" ),
                        new Place( new Coordinate( 43.65, -93.00 ), "Austin Acres, MN, US", "Mower", "http://www.yr.no/place/United_States/Minnesota/Austin_Acres~5016885/" ),
                        new Place( new Coordinate( 41.38, -75.74 ), "Austin Heights, PA, US", "Lackawanna", "http://www.yr.no/place/United_States/Pennsylvania/Austin_Heights~5178715/" ),
                        new Place( new Coordinate( 39.97, -86.24 ), "Austin Oaks, IN, US", "Hamilton", "http://www.yr.no/place/United_States/Indiana/Austin_Oaks~7118787/" ),
                        new Place( new Coordinate( 38.44, -77.42 ), "Austin Ridge, VA, US", "Stafford", "http://www.yr.no/place/United_States/Virginia/Austin_Ridge~7198132/" )
                    } :
                    file == CityFile.Eidal ? new[] {
                        new Place( new Coordinate( 60.08, 9.53 ), "Eiddal, Buskerud, NO", "Sigdal", "http://www.yr.no/place/Norway/Buskerud/Sigdal/Eiddal~3158724/" )
                    } :
                    file == CityFile.London ? new[] {
                        new Place( new Coordinate( 51.51, -0.13 ), "London, ENG, GB", "Greater London", "http://www.yr.no/place/United_Kingdom/England/London~2643743/" ),
                        new Place( new Coordinate( -33.02, 27.91 ), "East London, EC, ZA", "Buffalo", "http://www.yr.no/place/South_Africa/Eastern_Cape/East_London~1006984/" ),
                        new Place( new Coordinate( 42.98, -81.23 ), "London, ON, CA", "", "http://www.yr.no/place/Canada/Ontario/London~6058560/" ),
                        new Place( new Coordinate( 41.36, -72.10 ), "New London, CT, US", "New London", "http://www.yr.no/place/United_States/Connecticut/New_London~4839416/" ),
                        new Place( new Coordinate( 1.98, -157.48 ), "London Village, L, KI", "Kiritimati", "http://www.yr.no/place/Kiribati/Line_Islands/London_Village~4030939/" ),
                        new Place( new Coordinate( 2.27, 9.79 ), "London, GQ", "", "http://www.yr.no/place/Equatorial_Guinea/Other/London~2308696/" ),
                        new Place( new Coordinate( 40.93, -91.40 ), "New London, IA, US", "Henry", "http://www.yr.no/place/United_States/Iowa/New_London~4868768/" ),
                        new Place( new Coordinate( 44.39, -88.74 ), "New London, WI, US", "Waupaca", "http://www.yr.no/place/United_States/Wisconsin/New_London~5264455/" ),
                        new Place( new Coordinate( 51.35, -0.20 ), "London Borough of Sutton, ENG, GB", "Greater London", "http://www.yr.no/place/United_Kingdom/England/London_Borough_of_Sutton~2636503/" ),
                        new Place( new Coordinate( 43.41, -71.99 ), "New London, NH, US", "Merrimack", "http://www.yr.no/place/United_States/New_Hampshire/New_London~5090189/" ),
                        new Place( new Coordinate( 18.25, -78.22 ), "Little London, Westmoreland, JM", "", "http://www.yr.no/place/Jamaica/Westmoreland/Little_London~3489741/" ),
                        new Place( new Coordinate( 41.09, -82.40 ), "New London, OH, US", "Huron", "http://www.yr.no/place/United_States/Ohio/New_London~5164352/" ),
                        new Place( new Coordinate( 51.72, -0.30 ), "London Colney, ENG, GB", "Hertfordshire", "http://www.yr.no/place/United_Kingdom/England/London_Colney~2643738/" ),
                        new Place( new Coordinate( 35.33, -93.25 ), "London, AR, US", "Pope", "http://www.yr.no/place/United_States/Arkansas/London~4119617/" ),
                        new Place( new Coordinate( 32.24, -94.94 ), "New London, TX, US", "Rusk", "http://www.yr.no/place/United_States/Texas/New_London~4714475/" ),
                        new Place( new Coordinate( 39.89, -83.45 ), "London, OH, US", "Madison", "http://www.yr.no/place/United_States/Ohio/London~4517009/" ),
                        new Place( new Coordinate( 30.68, -99.58 ), "London, TX, US", "Kimble", "http://www.yr.no/place/United_States/Texas/London~4707414/" ),
                        new Place( new Coordinate( 43.05, -89.01 ), "London, WI, US", "Dane", "http://www.yr.no/place/United_States/Wisconsin/London~5260737/" ),
                        new Place( new Coordinate( 5.72, 5.79 ), "London, DE, NG", "", "http://www.yr.no/place/Nigeria/Delta/London~2331921/" ),
                        new Place( new Coordinate( 17.98, -88.43 ), "London, OW, BZ", "", "http://www.yr.no/place/Belize/Orange_Walk/London~3581797/" ),
                        new Place( new Coordinate( 36.48, -119.44 ), "London, CA, US", "Tulare", "http://www.yr.no/place/United_States/California/London~5367815/" ),
                        new Place( new Coordinate( 45.30, -94.94 ), "New London, MN, US", "Kandiyohi", "http://www.yr.no/place/United_States/Minnesota/New_London~5039111/" ),
                        new Place( new Coordinate( 35.44, -80.22 ), "New London, NC, US", "Stanly", "http://www.yr.no/place/United_States/North_Carolina/New_London~4481941/" ),
                        new Place( new Coordinate( 51.46, -0.19 ), "London Borough of Wandsworth, ENG, GB", "Greater London", "http://www.yr.no/place/United_Kingdom/England/London_Borough_of_Wandsworth~2634812/" ),
                        new Place( new Coordinate( 6.01, 125.13 ), "London, Soccsksargen, PH", "General Santos", "http://www.yr.no/place/Philippines/Soccsksargen/London~1705729/" ),
                        new Place( new Coordinate( 51.44, 0.15 ), "Bexley, ENG, GB", "Greater London", "http://www.yr.no/place/United_Kingdom/England/Bexley~2655775/" ),
                        new Place( new Coordinate( 38.19, -81.37 ), "London, WV, US", "Kanawha", "http://www.yr.no/place/United_States/West_Virginia/London~4812926/" ),
                        new Place( new Coordinate( 43.63, -123.09 ), "London Springs, OR, US", "Lane", "http://www.yr.no/place/United_States/Oregon/London_Springs~5737566/" ),
                        new Place( new Coordinate( -24.82, 31.05 ), "London, MP, ZA", "Ehlanzeni", "http://www.yr.no/place/South_Africa/Mpumalanga/London~982298/" ),
                        new Place( new Coordinate( 31.30, -87.09 ), "London, AL, US", "Conecuh", "http://www.yr.no/place/United_States/Alabama/London~4073570/" ),
                        new Place( new Coordinate( 37.13, -84.08 ), "London, KY, US", "Laurel", "http://www.yr.no/place/United_States/Kentucky/London~4298960/" ),
                        new Place( new Coordinate( -24.30, 30.57 ), "London, LP, ZA", "Mopani", "http://www.yr.no/place/South_Africa/Limpopo/London~982300/" ),
                        new Place( new Coordinate( 35.87, -83.00 ), "London, TN, US", "Cocke", "http://www.yr.no/place/United_States/Tennessee/London~4637795/" ),
                        new Place( new Coordinate( 42.02, -83.61 ), "London, MI, US", "Monroe", "http://www.yr.no/place/United_States/Michigan/London~4999913/" ),
                        new Place( new Coordinate( 43.53, -93.06 ), "London, MN, US", "Freeborn", "http://www.yr.no/place/United_States/Minnesota/London~5035439/" ),
                        new Place( new Coordinate( 47.20, -91.57 ), "London, MN, US", "Lake", "http://www.yr.no/place/United_States/Minnesota/London~5035441/" ),
                        new Place( new Coordinate( 40.44, -95.23 ), "London, MO, US", "Atchison", "http://www.yr.no/place/United_States/Missouri/London~5056033/" ),
                        new Place( new Coordinate( 40.91, -82.63 ), "London, OH, US", "Richland", "http://www.yr.no/place/United_States/Ohio/London~5161176/" ),
                        new Place( new Coordinate( 43.63, -123.09 ), "London, OR, US", "Lane", "http://www.yr.no/place/United_States/Oregon/London~5737562/" ),
                        new Place( new Coordinate( 39.42, -77.25 ), "New London, MD, US", "Frederick", "http://www.yr.no/place/United_States/Maryland/New_London~4363653/" ),
                        new Place( new Coordinate( 36.84, -76.05 ), "London Bridge, VA, US", "", "http://www.yr.no/place/United_States/Virginia/London_Bridge~4770418/" ),
                        new Place( new Coordinate( 38.14, -77.32 ), "New London, VA, US", "Caroline", "http://www.yr.no/place/United_States/Virginia/New_London~4775854/" ),
                        new Place( new Coordinate( 40.44, -86.27 ), "New London, IN, US", "Howard", "http://www.yr.no/place/United_States/Indiana/New_London~4924126/" )
                    } :
                    file == CityFile.Montevideo ? new[] {
                        new Place( new Coordinate( -34.83, -56.17 ), "Montevideo, MO, UY", "", "http://www.yr.no/place/Uruguay/Montevideo/Montevideo~3441575/" ),
                        new Place( new Coordinate( 9.38, -75.12 ), "Montevideo, SUC, CO", "", "http://www.yr.no/place/Colombia/Sucre/Montevideo~3674428/" ),
                        new Place( new Coordinate( 44.95, -95.72 ), "Montevideo, MN, US", "Chippewa", "http://www.yr.no/place/United_States/Minnesota/Montevideo~5038018/" ),
                        new Place( new Coordinate( -7.20, -79.52 ), "Montevideo, LAL, PE", "Chepen", "http://www.yr.no/place/Peru/La_Libertad/Montevideo~3694608/" ),
                        new Place( new Coordinate( 15.72, -86.90 ), "Montevideo, AT, HN", "", "http://www.yr.no/place/Honduras/Atlántida/Montevideo~3604603/" ),
                        new Place( new Coordinate( 10.10, -65.74 ), "Montevideo, M, VE", "", "http://www.yr.no/place/Venezuela/Miranda/Montevideo~3631999/" ),
                        new Place( new Coordinate( 9.87, -70.13 ), "Montevideo, K, VE", "", "http://www.yr.no/place/Venezuela/Lara/Montevideo~3632000/" ),
                        new Place( new Coordinate( 9.55, -65.80 ), "Montevideo, J, VE", "", "http://www.yr.no/place/Venezuela/Guárico/Montevideo~3632001/" ),
                        new Place( new Coordinate( 7.70, -75.48 ), "Montevideo, ANT, CO", "", "http://www.yr.no/place/Colombia/Antioquia/Montevideo~3674430/" ),
                        new Place( new Coordinate( 7.42, -80.52 ), "Montevideo, Los Santos, PA", "", "http://www.yr.no/place/Panama/Los_Santos/Montevideo~3704128/" ),
                        new Place( new Coordinate( 7.32, -73.30 ), "Montevideo, SAN, CO", "", "http://www.yr.no/place/Colombia/Santander/Montevideo~3732184/" ),
                        new Place( new Coordinate( 8.64, -76.05 ), "Montevideo, COR, CO", "", "http://www.yr.no/place/Colombia/Córdoba/Montevideo~3779592/" ),
                        new Place( new Coordinate( 3.42, -74.92 ), "Montevideo, TOL, CO", "", "http://www.yr.no/place/Colombia/Tolima/Montevideo~3828268/" ),
                        new Place( new Coordinate( -14.73, -61.92 ), "Montevideo, S, BO", "", "http://www.yr.no/place/Bolivia/Santa_Cruz/Montevideo~3909995/" ),
                        new Place( new Coordinate( -14.55, -64.93 ), "Montevideo, B, BO", "", "http://www.yr.no/place/Bolivia/El_Beni/Montevideo~3909996/" ),
                        new Place( new Coordinate( 5.95, -72.17 ), "Montevideo, CAS, CO", "", "http://www.yr.no/place/Colombia/Casanare/Montevideo~3674431/" ),
                        new Place( new Coordinate( -10.30, -67.12 ), "Montevideo, N, BO", "", "http://www.yr.no/place/Bolivia/Pando/Montevideo~3909998/" ),
                        new Place( new Coordinate( 23.21, -100.02 ), "Montevideo, TAM, MX", "", "http://www.yr.no/place/Mexico/Tamaulipas/Montevideo~3971766/" ),
                        new Place( new Coordinate( 25.01, -101.37 ), "Montevideo, COA, MX", "", "http://www.yr.no/place/Mexico/Coahuila/Montevideo~3977381/" ),
                        new Place( new Coordinate( 34.27, -82.82 ), "Montevideo, GA, US", "Elbert", "http://www.yr.no/place/United_States/Georgia/Montevideo~4209926/" ),
                        new Place( new Coordinate( -9.37, -75.88 ), "Montevideo, HUC, PE", "Leoncio Prado", "http://www.yr.no/place/Peru/Huanuco/Montevideo~6659384/" ),
                        new Place( new Coordinate( -20.32, -69.87 ), "Montevideo, TA, CL", "Tamarugal", "http://www.yr.no/place/Chile/Tarapacá/Montevideo~3879419/" ),
                        new Place( new Coordinate( 39.16, -76.77 ), "Montevideo, MD, US", "Anne Arundel", "http://www.yr.no/place/United_States/Maryland/Montevideo~4362705/" ),
                        new Place( new Coordinate( 38.36, -78.77 ), "Montevideo, VA, US", "Rockingham", "http://www.yr.no/place/United_States/Virginia/Montevideo~4773698/" ),
                        new Place( new Coordinate( -32.22, -55.60 ), "Poblado Montevideo Chico, TA, UY", "", "http://www.yr.no/place/Uruguay/Tacuarembó/Poblado_Montevideo_Chico~3441028/" ),
                        new Place( new Coordinate( -5.32, -43.92 ), "Montevidéu, MA, BR", "Senador Alexandre Costa", "http://www.yr.no/place/Brazil/Maranhão/Montevidéu~3394524/" ),
                        new Place( new Coordinate( -6.62, -77.80 ), "Montevideo, AMA, PE", "Chachapoyas", "http://www.yr.no/place/Peru/Amazonas/Montevideo~3694609/" ),
                        new Place( new Coordinate( -32.25, -56.52 ), "Montevideo Chico, PA, UY", "", "http://www.yr.no/place/Uruguay/Paysandú/Montevideo_Chico~3441570/" ),
                        new Place( new Coordinate( 9.74, -73.95 ), "Hacienda Montevideo, MAG, CO", "", "http://www.yr.no/place/Colombia/Magdalena/Hacienda_Montevideo~3674427/" ),
                        new Place( new Coordinate( -22.23, -57.63 ), "Retiro, Concepción, PY", "", "http://www.yr.no/place/Paraguay/Concepción/Retiro~3437193/" ),
                        new Place( new Coordinate( 8.75, -75.75 ), "Montevideo, COR, CO", "", "http://www.yr.no/place/Colombia/Córdoba/Montevideo~3783632/" ),
                        new Place( new Coordinate( -7.36, -38.42 ), "Montevidéo, PB, BR", "Conceição", "http://www.yr.no/place/Brazil/Paraíba/Montevidéo~6317639/" ),
                        new Place( new Coordinate( -32.53, -58.93 ), "Villa Nueva Montevideo, E, AR", "", "http://www.yr.no/place/Argentina/Entre_Ríos/Villa_Nueva_Montevideo~3427390/" ),
                        new Place( new Coordinate( -13.98, -62.27 ), "San Vicente Montevideo, B, BO", "", "http://www.yr.no/place/Bolivia/El_Beni/San_Vicente_Montevideo~3904613/" ),
                        new Place( new Coordinate( -22.62, -43.40 ), "Cidade Jardim Montevideo, RJ, BR", "Nova Iguaçu", "http://www.yr.no/place/Brazil/Rio_de_Janeiro/Cidade_Jardim_Montevideo~3480635/" ),
                        new Place( new Coordinate( 4.65, -74.12 ), "Montevideo, DC, CO", "", "http://www.yr.no/place/Colombia/Bogotá/Montevideo~7033380/" ),
                        new Place( new Coordinate( 24.80, -104.81 ), "Rancho San Isidro Montevideo, DUR, MX", "", "http://www.yr.no/place/Mexico/Durango/Rancho_San_Isidro_Montevideo~3989263/" )
                    } :
                    file == CityFile.Rome ? new[] {
                        new Place( new Coordinate( 41.89, 12.48 ), "Rome, Latium, IT", "Rome", "http://www.yr.no/place/Italy/Latium/Rome~3169070/" ),
                        new Place( new Coordinate( 6.14, 1.21 ), "Lomé, M, TG", "", "http://www.yr.no/place/Togo/Maritime/Lomé~2365267/" ),
                        new Place( new Coordinate( -3.63, 133.68 ), "Rome, PB, ID", "", "http://www.yr.no/place/Indonesia/West_Papua/Rome~1622597/" ),
                        new Place( new Coordinate( 34.26, -85.16 ), "Rome, GA, US", "Floyd", "http://www.yr.no/place/United_States/Georgia/Rome~4219762/" ),
                        new Place( new Coordinate( 44.59, -69.87 ), "Rome, ME, US", "Kennebec", "http://www.yr.no/place/United_States/Maine/Rome~4976934/" ),
                        new Place( new Coordinate( 40.88, -89.50 ), "Rome, IL, US", "Peoria", "http://www.yr.no/place/United_States/Illinois/Rome~4908066/" ),
                        new Place( new Coordinate( 41.50, -85.38 ), "Rome City, IN, US", "Noble", "http://www.yr.no/place/United_States/Indiana/Rome_City~4925561/" ),
                        new Place( new Coordinate( 36.26, -86.07 ), "Rome, TN, US", "Smith", "http://www.yr.no/place/United_States/Tennessee/Rome~4654344/" ),
                        new Place( new Coordinate( 40.98, -91.68 ), "Rome, IA, US", "Henry", "http://www.yr.no/place/United_States/Iowa/Rome~4873535/" ),
                        new Place( new Coordinate( 42.98, -88.63 ), "Rome, WI, US", "Jefferson", "http://www.yr.no/place/United_States/Wisconsin/Rome~5269443/" ),
                        new Place( new Coordinate( 42.84, -117.63 ), "Rome, OR, US", "Malheur", "http://www.yr.no/place/United_States/Oregon/Rome~5749249/" ),
                        new Place( new Coordinate( 37.92, -86.52 ), "Rome, IN, US", "Perry", "http://www.yr.no/place/United_States/Indiana/Rome~4048394/" ),
                        new Place( new Coordinate( 37.72, -87.18 ), "Rome, KY, US", "Daviess", "http://www.yr.no/place/United_States/Kentucky/Rome~4306693/" ),
                        new Place( new Coordinate( 33.96, -90.48 ), "Rome, MS, US", "Sunflower", "http://www.yr.no/place/United_States/Mississippi/Rome~4443788/" ),
                        new Place( new Coordinate( 41.86, -76.34 ), "Rome, PA, US", "Bradford", "http://www.yr.no/place/United_States/Pennsylvania/Rome~5208923/" ),
                        new Place( new Coordinate( 43.21, -75.46 ), "Rome, NY, US", "Oneida", "http://www.yr.no/place/United_States/New_York/Rome~5134295/" ),
                        new Place( new Coordinate( 51.79, 5.32 ), "Rome, GE, NL", "Gemeente Maasdriel", "http://www.yr.no/place/Netherlands/Gelderland/Rome~2747972/" ),
                        new Place( new Coordinate( 18.42, -78.05 ), "Rome, Hanover, JM", "", "http://www.yr.no/place/Jamaica/Hanover/Rome~3488761/" ),
                        new Place( new Coordinate( 39.95, -83.14 ), "New Rome, OH, US", "Franklin", "http://www.yr.no/place/United_States/Ohio/New_Rome~4519668/" ),
                        new Place( new Coordinate( 44.22, -89.88 ), "New Rome, WI, US", "Adams", "http://www.yr.no/place/United_States/Wisconsin/New_Rome~5264485/" ),
                        new Place( new Coordinate( 50.70, 3.70 ), "Rome, WAL, BE", "Hainaut", "http://www.yr.no/place/Belgium/Wallonia/Rome~2787825/" ),
                        new Place( new Coordinate( 44.27, 3.22 ), "Saint-Rome-de-Dolan, K, FR", "Lozère", "http://www.yr.no/place/France/Languedoc-Roussillon/Saint-Rome-de-Dolan~2977108/" ),
                        new Place( new Coordinate( 31.14, -86.67 ), "Rome, AL, US", "Covington", "http://www.yr.no/place/United_States/Alabama/Rome~4086964/" ),
                        new Place( new Coordinate( 43.41, 1.68 ), "Saint-Rome, N, FR", "Upper Garonne", "http://www.yr.no/place/France/Midi-Pyrénées/Saint-Rome~2977111/" ),
                        new Place( new Coordinate( 41.71, -8.76 ), "Romé, Viana do Castelo, PT", "Viana do Castelo", "http://www.yr.no/place/Portugal/Viana_do_Castelo/Romé~2735020/" ),
                        new Place( new Coordinate( 39.96, -83.14 ), "Rome, OH, US", "Franklin", "http://www.yr.no/place/United_States/Ohio/Rome~4050082/" ),
                        new Place( new Coordinate( 36.84, -92.77 ), "Rome, MO, US", "Douglas", "http://www.yr.no/place/United_States/Missouri/Rome~4406321/" ),
                        new Place( new Coordinate( 33.10, -89.24 ), "Rome, MS, US", "Winston", "http://www.yr.no/place/United_States/Mississippi/Rome~4443789/" ),
                        new Place( new Coordinate( 38.45, -82.36 ), "Rome, OH, US", "Lawrence", "http://www.yr.no/place/United_States/Ohio/Rome~4522805/" ),
                        new Place( new Coordinate( 40.25, -82.91 ), "Rome, OH, US", "Delaware", "http://www.yr.no/place/United_States/Ohio/Rome~5168563/" ),
                        new Place( new Coordinate( 40.93, -82.53 ), "Rome, OH, US", "Richland", "http://www.yr.no/place/United_States/Ohio/Rome~5168564/" ),
                        new Place( new Coordinate( 44.22, -89.81 ), "Rome, WI, US", "Adams", "http://www.yr.no/place/United_States/Wisconsin/Rome~8503114/" ),
                        new Place( new Coordinate( 37.16, -97.14 ), "Rome, KS, US", "Sumner", "http://www.yr.no/place/United_States/Kansas/Rome~4278300/" ),
                        new Place( new Coordinate( 30.38, -90.55 ), "Rome, LA, US", "Livingston", "http://www.yr.no/place/United_States/Louisiana/Rome~4339061/" ),
                        new Place( new Coordinate( 33.65, -79.44 ), "Rome, SC, US", "Williamsburg", "http://www.yr.no/place/United_States/South_Carolina/Rome~4593412/" ),
                        new Place( new Coordinate( 44.44, -73.69 ), "Rome, NY, US", "Essex", "http://www.yr.no/place/United_States/New_York/Rome~5134294/" ),
                        new Place( new Coordinate( 44.05, 2.90 ), "Saint-Rome-de-Tarn, N, FR", "Aveyron", "http://www.yr.no/place/France/Midi-Pyrénées/Saint-Rome-de-Tarn~2977107/" ),
                        new Place( new Coordinate( 44.01, 2.96 ), "Saint-Rome-de-Cernon, N, FR", "Aveyron", "http://www.yr.no/place/France/Midi-Pyrénées/Saint-Rome-de-Cernon~2977109/" ),
                        new Place( new Coordinate( 43.87, 3.17 ), "Saint-Rome, N, FR", "Aveyron", "http://www.yr.no/place/France/Midi-Pyrénées/Saint-Rome~2977110/" ),
                        new Place( new Coordinate( 41.60, -80.87 ), "Rome, OH, US", "Ashtabula", "http://www.yr.no/place/United_States/Ohio/Rome~5168562/" ),
                        new Place( new Coordinate( 45.58, 3.25 ), "La Rome, C, FR", "Puy-de-Dôme", "http://www.yr.no/place/France/Auvergne/La_Rome~3006737/" ),
                        new Place( new Coordinate( 34.22, -85.18 ), "New Rome, GA, US", "Floyd", "http://www.yr.no/place/United_States/Georgia/New_Rome~4212549/" ),
                        new Place( new Coordinate( 34.26, -85.16 ), "North Rome, GA, US", "Floyd", "http://www.yr.no/place/United_States/Georgia/North_Rome~4213131/" ),
                        new Place( new Coordinate( 34.28, -85.23 ), "West Rome, GA, US", "Floyd", "http://www.yr.no/place/United_States/Georgia/West_Rome~4230272/" ),
                        new Place( new Coordinate( 44.57, -69.90 ), "Rome Corner, ME, US", "Kennebec", "http://www.yr.no/place/United_States/Maine/Rome_Corner~4976935/" )
                    } :
                    file == CityFile.Sammamish ? new[] {
                        new Place( new Coordinate( 47.60, -122.04 ), "City of Sammamish, WA, US", "King", "http://www.yr.no/place/United_States/Washington/City_of_Sammamish~7174365/" )
                    } :
                    file == CityFile.Sydney ? new[] {
                        new Place( new Coordinate( -33.87, 151.21 ), "Sydney, NSW, AU", "", "http://www.yr.no/place/Australia/New_South_Wales/Sydney~2147714/" ),
                        new Place( new Coordinate( 46.14, -60.18 ), "Sydney, NS, CA", "", "http://www.yr.no/place/Canada/Nova_Scotia/Sydney~6354908/" ),
                        new Place( new Coordinate( -33.84, 151.21 ), "North Sydney, NSW, AU", "North Sydney", "http://www.yr.no/place/Australia/New_South_Wales/North_Sydney~2154855/" ),
                        new Place( new Coordinate( 49.42, 4.10 ), "Poilcourt-Sydney, G, FR", "Ardennes", "http://www.yr.no/place/France/Champagne-Ardenne/Poilcourt-Sydney~2986553/" ),
                        new Place( new Coordinate( -19.53, 169.27 ), "Sydney, TAE, VU", "", "http://www.yr.no/place/Vanuatu/Tafea/Sydney~2134763/" ),
                        new Place( new Coordinate( -33.87, 151.22 ), "East Sydney, NSW, AU", "", "http://www.yr.no/place/Australia/New_South_Wales/East_Sydney~8504548/" ),
                        new Place( new Coordinate( -26.22, 23.12 ), "Sydney, NW, ZA", "", "http://www.yr.no/place/South_Africa/North-West/Sydney~950662/" ),
                        new Place( new Coordinate( 37.24, -78.46 ), "Hampden Sydney, VA, US", "Prince Edward", "http://www.yr.no/place/United_States/Virginia/Hampden_Sydney~4762888/" ),
                        new Place( new Coordinate( 46.24, -60.22 ), "Sydney Mines, NS, CA", "", "http://www.yr.no/place/Canada/Nova_Scotia/Sydney_Mines~7303783/" ),
                        new Place( new Coordinate( -33.86, 151.21 ), "Sydney CBD, NSW, AU", "", "http://www.yr.no/place/Australia/New_South_Wales/Sydney_CBD~6619280/" ),
                        new Place( new Coordinate( -28.44, 24.32 ), "Sydney on Vaal, NC, ZA", "Frances Baard", "http://www.yr.no/place/South_Africa/Northern_Cape/Sydney_on_Vaal~950661/" ),
                        new Place( new Coordinate( 37.62, -82.36 ), "Sydney, KY, US", "Pike", "http://www.yr.no/place/United_States/Kentucky/Sydney~7122098/" ),
                        new Place( new Coordinate( 46.15, -60.18 ), "Sydney, NS, CA", "", "http://www.yr.no/place/Canada/Nova_Scotia/Sydney~6160752/" ),
                        new Place( new Coordinate( 46.12, -60.22 ), "Sydney River, NS, CA", "", "http://www.yr.no/place/Canada/Nova_Scotia/Sydney_River~6160771/" ),
                        new Place( new Coordinate( 46.21, -60.26 ), "North Sydney, NS, CA", "", "http://www.yr.no/place/Canada/Nova_Scotia/North_Sydney~6930307/" ),
                        new Place( new Coordinate( 27.96, -82.21 ), "Sydney, FL, US", "Hillsborough", "http://www.yr.no/place/United_States/Florida/Sydney~4174663/" ),
                        new Place( new Coordinate( 46.73, -98.77 ), "Sydney, ND, US", "Stutsman", "http://www.yr.no/place/United_States/North_Dakota/Sydney~5062142/" ),
                        new Place( new Coordinate( 37.58, -82.37 ), "Old Sydney, KY, US", "Pike", "http://www.yr.no/place/United_States/Kentucky/Old_Sydney~7140791/" ),
                        new Place( new Coordinate( 27.99, -82.18 ), "Sydney Crossings, FL, US", "Hillsborough", "http://www.yr.no/place/United_States/Florida/Sydney_Crossings~7219617/" ),
                        new Place( new Coordinate( 37.80, -122.40 ), "Sydney Town, CA, US", "San Francisco", "http://www.yr.no/place/United_States/California/Sydney_Town~5400754/" )
                    } :
                    file == CityFile.Tokyo ? new[] {
                        new Place( new Coordinate( 35.69, 139.69 ), "Tokyo, Tōkyō, JP", "", "http://www.yr.no/place/Japan/Tōkyō/Tokyo~1850147/" ),
                        new Place( new Coordinate( 7.34, 134.48 ), "Koror Town, Koror, PW", "", "http://www.yr.no/place/Palau/Koror/Koror_Town~7732415/" ),
                        new Place( new Coordinate( 35.73, 139.54 ), "Nishi-Tokyo-shi, Tōkyō, JP", "", "http://www.yr.no/place/Japan/Tōkyō/Nishi-Tokyo-shi~1850692/" ),
                        new Place( new Coordinate( -8.40, 147.15 ), "Tokyo, CPM, PG", "", "http://www.yr.no/place/Papua_New_Guinea/Central/Tokyo~2085290/" ),
                        new Place( new Coordinate( 29.17, 83.16 ), "Tokyo, Mid Western, NP", "Karnālī Zone", "http://www.yr.no/place/Nepal/Mid_Western/Tokyo~7945384/" ),
                        new Place( new Coordinate( 34.05, -118.24 ), "Little Tokyo, CA, US", "Los Angeles", "http://www.yr.no/place/United_States/California/Little_Tokyo~5367260/" )
                    } :
                    null;
            }

            return _fileData[index];
        }

        private static Place[] LoadCities( CityFile file ) {
            string resourceName = "search" + file.ToString( ) + ".xml";

            using( var source = typeof( TestPlace ).Assembly.GetManifestResourceStream( typeof( TestPlace ), resourceName ) )
                return Place.Load( default( Units ), source, default( Place.Corrections ) );
        }

        private static Place[] DownloadCities( CityFile file ) {
            var address = new Uri( @"http://api.geonames.org/search?username=WeatherSpark&isNameRequired=true&featureClass=P&style=FULL&maxRows=45&q=" + file.ToString( ).Replace( "_", "%2c" ) );
            using( var client = new WebClient( ) ) {
                byte[] contents = client.DownloadData( address );

                using( var source = new MemoryStream( contents ) )
                    return Place.Load( default( Units ), source, default( Place.Corrections ) );
            }
        }


        public enum CityFile {
            Austin_TX = 0,
            Austin,
            Eidal,
            London,
            Montevideo,
            Rome,
            Sammamish,
            Sydney,
            Tokyo,
        }

        #endregion
    }

}
